#ifndef __PTGUI_PAGECTL_H__
#define __PTGUI_PAGECTL_H__

#include <gal/ptgui.h>
#ifdef __cplusplus
extern "C"
{
#endif

typedef enum {
	PAGE_FLAG_NONE,
	PAGE_FLAG_FULL_SCREEN = PT_MASK_DEF(1),
	PAGE_FLAG_FULL_OPAQUE = PT_MASK_DEF(2),
} ptgui_page_flag_t;
#define PAGE_FLAG_DEFAULT (PAGE_FLAG_FULL_SCREEN | PAGE_FLAG_FULL_OPAQUE)

typedef enum {
	PAGE_SW_STAT_NONE,
	PAGE_SW_STAT_VISIBLE = PT_MASK_DEF(1),
	PAGE_SW_STAT_SELECTED_1 = PT_MASK_DEF(2),
	PAGE_SW_STAT_SELECTED_2 = PT_MASK_DEF(3),
	PAGE_SW_STAT_SELECTED_3 = PT_MASK_DEF(4),	
	PAGE_SW_STAT_FORBIDDEN = PT_MASK_DEF(5)
} ptgui_page_sw_state_t;

/*	Forbidden Control Check	*/
#define	ptgui_isAvailableControl(attribute)		(!((attribute)&PAGE_SW_STAT_FORBIDDEN))

/*	Key Trigger	*/
typedef enum {
	KEY_ON_DO = PT_MASK_DEF(1),
	KEY_OFF_DO = PT_MASK_DEF(2),
	KEY_OUT1_DO = PT_MASK_DEF(3),
	KEY_OUTOFF1_DO = PT_MASK_DEF(4),	
	KEY_OUT2_DO = PT_MASK_DEF(5),
	KEY_OUTOFF2_DO = PT_MASK_DEF(6),
	KEY_MOVEIN_DO = PT_MASK_DEF(7),
	KEY_MOVEOUT_DO = PT_MASK_DEF(8)
} ptgui_page_key_trigger_t;

typedef enum {
	PTGUI_PAGE_KEY_TYPE_NORMAL = 0	,	/*	0	*/
	PTGUI_PAGE_KEY_TYPE_BALFAD		,	/*	1	*/
	
	PTGUI_PAGE_KEY_TYPE_MAX
} ptgui_page_key_type_t;

typedef	pt_uint16_t	ptgui_page_view_handle_t;

typedef enum {
	PTGUI_PAGE_PREPARE_FST,
	PTGUI_PAGE_PREPARE_ALL,
	PTGUI_PAGE_TERMINATE_ALL,
	PTGUI_PAGE_TERMINATE_LST
} ptgui_page_entry_type_t;

typedef  struct	ptgui_page_control* ptgui_page_control_t;

typedef 	void	(*ptgui_page_entry_handler_t)(ptgui_page_entry_type_t);
typedef 	void	(*ptgui_page_frame_handler_t)(const struct ptgui_page_cell *page_cell, pt_uint32_t delta);
typedef 	void	(*ptgui_page_render_handler_t)(const struct ptgui_page_cell *page_cell);

typedef		struct	ptgui_page_control	*(*ptgui_page_event_handler_t)(pt_event_t*);
typedef 	ptgui_page_sw_state_t	(*ptgui_page_check_view_handler_t)(struct ptgui_page_switch_view*);

typedef enum {
	RTGUI_PAGE_STACK_TYPE_LOWER,
	RTGUI_PAGE_STACK_TYPE_NORMAL,
	RTGUI_PAGE_STACK_TYPE_UPPER,

	RTGUI_PAGE_STACK_TYPE_NONE,
	RTGUI_PAGE_STACK_TYPE_MAX
} ptgui_page_stack_type_t;

/*	Touch Key Define	*/
typedef	struct	ptgui_page_switch_view {
	ptgui_page_check_view_handler_t		check_view_handler;
	ptgui_page_event_handler_t			event_handler;
	pt_uint16_t			string_id;							
	pt_uint8_t			position_id;
	pt_uint8_t			draw_func_id;
	pt_uint8_t			key_type;
	pt_uint8_t			key_trigger;
} ptgui_page_switch_view_t;

/*	event_id Accept Table Node	*/
typedef	struct	ptgui_page_event_accept {
	pt_uint16_t		message;			
	ptgui_page_event_handler_t		event_handler;			
} ptgui_page_event_accept_t;

/*	Page Cell	*/
typedef	struct	ptgui_page_cell	{
	const	ptgui_page_event_accept_t	*event_accept;				
	const	ptgui_page_switch_view_t	* const *switch_view;			
	ptgui_page_entry_handler_t	entry_handler;	
	ptgui_page_frame_handler_t	frame_handler;
	ptgui_page_render_handler_t	render_handler;		
	ptgui_page_view_handle_t	viewHandle;	
	pt_uint32_t					flag;					
} ptgui_page_cell_t;

/*	Pile Node	*/
typedef	struct	ptgui_page_stack {
	const ptgui_page_cell_t		*page_cell;				
	pt_uint32_t					transfer_status;
	ptgui_page_view_handle_t	view_handle;
	ptgui_container_t			*container;	
} ptgui_page_stack_t;

/*	Page control bucket	*/
struct	ptgui_page_control{
	const ptgui_page_cell_t		*request_page_cell;	
	pt_uint32_t		transfer_status;	
	pt_uint16_t		transfer_layer;		// 00010000 = dynamic stack
										// 0010xxxx = lower fix layer
										// 0100xxxx = upper fix layer
};

/*******************************************************************************
*	Macro for Page Making
*******************************************************************************/
/*	definition of event acception table	*/
#define	PTGUI_PAGE_BEGIN_DEF_EVENT_ACCEPT	\
	static	ptgui_page_event_accept_t	const	page_event_accept[] = {
#define	PTGUI_PAGE_DEF_EVENT_ACCEPT(event,function)	{(event),(ptgui_page_event_handler_t)(function)}
#define	PTGUI_PAGE_END_DEF_EVENT_ACCEPT	\
	{0,PT_NULL}}

/*	definition of visual switch	*/
#define	PTGUI_PAGE_DEF_SW_VIEW(name,proc,attr,bmp,possize,draw,trigger)	\
	ptgui_page_sw_state_t	attr(ptgui_page_switch_view_t*);					\
	ptgui_page_control_t	proc(pt_event_t*);							\
	static	ptgui_page_switch_view_t	const	name={(ptgui_page_check_view_handler_t)(attr),	\
				(ptgui_page_event_handler_t)(proc),(bmp),(possize),(draw),	\
				(PTGUI_PAGE_KEY_TYPE_NORMAL),(trigger)}
#define	PTGUI_PAGE_DEF_SW_VIEW_STATIC(name,proc,attr,bmp,possize,draw,trigger)	\
	static ptgui_page_sw_state_t	 attr(ptgui_page_switch_view_t*);					\
	static ptgui_page_control_t proc(pt_event_t*);							\
	static ptgui_page_switch_view_t	 const name={(ptgui_page_check_view_handler_t)(attr),	\
				(ptgui_page_event_handler_t)(proc),(bmp),(possize),(draw),	\
				(PTGUI_PAGE_KEY_TYPE_NORMAL),(trigger)}

#define	PTGUI_PAGE_BEGIN_REF_SW_VIEW_TABLE		\
	static	ptgui_page_switch_view_t*	const	page_switch_views[] = {
#define	PTGUI_PAGE_REF_SW_VIEW(name)	(ptgui_page_switch_view_t*)(&name)
#define	PTGUI_PAGE_END_REF_SW_VIEW_TABLE(Name)		\
	PT_NULL};

#define	PTGUI_PAGE_DEF_PAGECELL(Name, Flag)							\
ptgui_page_cell_t	const	PageCell_##Name = {	\
										page_event_accept,		\
										page_switch_views,	\
										ptgui_page_entry_handler,		\
										ptgui_page_frame_handler,		\
										ptgui_page_render_handler,		\
										PTGUI_PAGE_VIEWHANDLE_INDEX(Name),	\
										Flag			}

#define	PTGUI_PAGE_DEC_PAGECELL(Name)							\
extern ptgui_page_cell_t	const	PageCell_##Name

#define	PTGUI_PAGE_REF_PAGECELL(Name)	(ptgui_page_cell_t* )&PageCell_##Name

/* Page Transfer Control */
/*****	do not transfer	*****/
#define	PTGUI_PAGE_TRAN_KEEP_FLAT	(PT_NULL)
/*****	do not transfer	*****/
#define	PTGUI_PAGE_TRAN_BREAK_FUNC	ptgui_page_transfer_break()
void ptgui_page_key_event_break(void);
/*******************************************************************************
*
*	Definition of Transfer Switch
*
*	0	0	0	0	:	0	0	0	0	:	0	0	0	0	:	0	0	0	0
*	Inherit on(1)		Insurance on(1)		reserved			ride(1)/return(2)
*	/off(0)				/off(0)									/change(4)
*																/rewind(8)
*
*	0	0	0	0	:	0	0	0	0	:	0	0	0	0	:	0	0	0	0
*	dependence(1)		reserved			reserved			drawing inhibition all(1)
*																/only direct(2)
*																/only base(4)
*
*******************************************************************************/
/*	inhibition switch for lower pile	*/
#define	INHIBITION_ALL_DRAWINGS			(0x00000001L)
#define	INHIBITION_DIRECT_DRAWINGS		(0x00000002L)
#define	INHIBITION_EXCEPT_BASE_DRAWINGS	(0x00000004L)
#define	INHIBITION_MASK_DRAWINGS		(INHIBITION_DIRECT_DRAWINGS|INHIBITION_ALL_DRAWINGS|INHIBITION_EXCEPT_BASE_DRAWINGS)

#define	INHIBITION_NONE					(0x00000000L)
#define	INHIBITION_ALL					(INHIBITION_ALL_DRAWINGS)
#define	INHIBITION_DIRECT				(INHIBITION_DIRECT_DRAWINGS)
#define	INHIBITION_EXCEPT_BASE			(INHIBITION_EXCEPT_BASE_DRAWINGS)

/*	inherit	*/
#define	INHERIT_OFF						(0x00000000L)	
#define	INHERIT_ON						(0x10000000L)	

/*	insurance	*/
#define	INSURANCE_OFF					(0x00000000L)	
#define	INSURANCE_ON					(0x01000000L)	

#define	PTGUI_PAGE_LEVEL_UP						(0x00010000L)
#define	PTGUI_PAGE_LEVEL_DOWN					(0x00020000L)
#define	PTGUI_PAGE_LEVEL_KEEP					(0x00040000L)
#define	PTGUI_PAGE_LEVEL_REWIND					(0x00080000L)
#define	PTGUI_PAGE_LEVEL_DEPEND					(0x00001000L)

/*	Change	*/
#define	PAGE_CHANGE		(PTGUI_PAGE_LEVEL_KEEP)
/*	RIDE	*/
#define	PAGE_RIDE		((PTGUI_PAGE_LEVEL_UP)|(PTGUI_PAGE_LEVEL_DEPEND))	
/*	Float	*/
#define	PAGE_FLOAT		(INHERIT_ON|PTGUI_PAGE_LEVEL_UP)		
/*	Return	*/
#define	PAGE_RETURN		(PTGUI_PAGE_LEVEL_DOWN)				
#define	PAGE_REWIND		(PTGUI_PAGE_LEVEL_REWIND)	

//########################## Fix Pile Transfer Control ###########################
#define	PTGUI_PAGE_LAYER_NORMAL_MASK		(0x1000)
#define	PTGUI_PAGE_LAYER_LOWER_MASK			(0x2000)
#define	PTGUI_PAGE_LAYER_UPPER_MASK			(0x4000)

#define	PTGUI_PAGE_LAYER_MAKE_LOWER(layer)	(PTGUI_PAGE_LAYER_LOWER_MASK | (layer))
#define	PTGUI_PAGE_LAYER_MAKE_UPPER(layer)	(PTGUI_PAGE_LAYER_UPPER_MASK | (layer))
#define	PTGUI_PAGE_LAYER_MAKE_NORMAL(layer)	(PTGUI_PAGE_LAYER_NORMAL_MASK | (layer))

//------------------- Delete a page from Fix layer(lower/upper)--------------
#define	PTGUI_PAGE_DELETE_PILE_BYLAYER(layer)	\
	(ptgui_page_delete_stack_pile(layer))

/*******************************************************************************
*	FIX Layer Ride and Call
*******************************************************************************/
#define	PTGUI_PAGE_FIX_RIDE_REQUEST(cell,layer)		\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RIDE, INHIBITION_NONE, cell,layer))
#define	PTGUI_PAGE_FIX_CALL_REQUEST(cell,layer)		\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RIDE, INHIBITION_ALL,  cell ,layer))
#define	PTGUI_PAGE_FIX_CALL_REQUEST_INH(cell, inhibition,layer)		\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RIDE, inhibition, cell  ,layer))

#define	PTGUI_PAGE_FIX_RIDE_REQUEST_INHERIT(cell,layer)		\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_RIDE, INHIBITION_NONE, cell  ,layer))
#define	PTGUI_PAGE_FIX_CALL_REQUEST_INHERIT(cell,layer)		\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_RIDE, INHIBITION_ALL, cell  ,layer))
#define	PTGUI_PAGE_FIX_CALL_REQUEST_INHERIT_INH(cell, inhibition,layer)		\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_RIDE, inhibition, cell ,layer))


/*******************************************************************************
*	Change
*******************************************************************************/
#define	PTGUI_PAGE_TRAN_CHANGE_REQUEST(cell)	\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_CHANGE, INHIBITION_NONE, cell,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_CHANGE_REQUEST_INHERIT(cell)	\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_CHANGE, INHIBITION_NONE, cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))
/*******************************************************************************
*	Ride and Call
*******************************************************************************/

#define	PTGUI_PTGUI_PAGE_RIDE_REQUEST(cell)		\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RIDE, INHIBITION_NONE,  cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))
#define	PTGUI_PAGE_TRAN_CALL_REQUEST(cell)		\
	ptgui_page_transfer_call_normal(PTGUI_PAGE_REF_PAGECELL(cell))
//	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RIDE, INHIBITION_ALL, cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))
#define	PAGE_CALL_REQUEST_INH(cell, inhibition)		\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RIDE, inhibition, cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_RIDE_REQUEST_INHERIT(cell)		\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_RIDE, INHIBITION_NONE,  cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))
#define	PAGE_CALL_REQUEST_INHERIT(cell)		\
	ptgui_page_transfer_call_inherit((ptgui_page_cell_t* )&PageCell##cell)
//	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_RIDE, INHIBITION_ALL, cell ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))
#define	PTGUI_PAGE_CALL_REQUEST_INHERIT_INH(cell, inhibition)		\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_RIDE, inhibition, cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))


/*******************************************************************************
*	Return and Rewind
*******************************************************************************/

#define	PTGUI_PAGE_TRAN_RETURN_REQUEST(cell)	\
	ptgui_page_transfer_return_normal()
//	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RETURN|INSURANCE_ON, INHIBITION_NONE, cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_REWIND_REQUEST(cell)	\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_REWIND|INSURANCE_ON, INHIBITION_NONE, cell ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_RETURN_REQUEST_TILL_BASE(cell)	\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_RETURN|INSURANCE_OFF,INHIBITION_NONE,  cell ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_REWIND_REQUEST_TILL_BASE(cell)	\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_REWIND|INSURANCE_OFF,INHIBITION_NONE, cell ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

/*******************************************************************************
*	Float
*******************************************************************************/

#define	PTGUI_PAGE_FLOAT_REQUEST(cell, priority)	\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_FLOAT, INHIBITION_NONE,  cell ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_FLOAT_REQUEST_INH(cell, priority, inhibition)	\
	(PTGUI_PAGE_TRANSFER_REQUEST(PAGE_FLOAT, inhibition, cell ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_FLOAT_REQUEST_INHERIT(cell, priority)	\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_FLOAT, INHIBITION_NONE,  cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

#define	PTGUI_PAGE_FLOAT_REQUEST_INHERIT_INH(cell, priority, inhibition)	\
	(PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(PAGE_FLOAT, inhibition,  cell  ,PTGUI_PAGE_LAYER_MAKE_NORMAL(0)))

/*******************************************************************************
*	plain macro to make PageControlBucket
*******************************************************************************/

/*****	for single page	*****/
#define	PTGUI_PAGE_TRANSFER_REQUEST(type, inhibition, cell ,layer)		\
	ptgui_page_make_transfer_control_bucket((type)|(inhibition), (ptgui_page_cell_t* )&PageCell_##cell,layer)

#define	PTGUI_PAGE_TRANSFER_REQUEST_INHERIT(type, inhibition, cell ,layer)		\
	ptgui_page_make_transfer_control_bucket(INHERIT_ON|(type)|(inhibition),  (ptgui_page_cell_t* )&PageCell_##cell,layer)

extern void ptgui_page_system_init(void);
extern void ptgui_page_system_free(void);

extern void ptgui_page_cycle_task_48ms(void);
extern pt_uint8_t ptgui_page_need_paint(void);

extern const ptgui_page_cell_t *ptgui_page_get_top_page(void);
extern pt_uint8_t ptgui_page_is_top_page(const ptgui_page_cell_t *page_cell);
extern pt_uint8_t ptgui_page_current_is_top_page(void);

extern ptgui_page_control_t ptgui_page_transfer_call_normal( ptgui_page_cell_t* requese_page );
extern ptgui_page_control_t ptgui_page_transfer_call_inherit( ptgui_page_cell_t* requese_page );
extern ptgui_page_control_t ptgui_page_transfer_return_normal( void );
extern ptgui_page_control_t ptgui_page_transfer_break(void);
extern ptgui_page_control_t ptgui_page_make_transfer_control_bucket(pt_uint32_t transfer_status,
															   const ptgui_page_cell_t *requese_page, pt_uint16_t	layer);
extern void ptgui_page_idle_handler(void);
extern void ptgui_page_event_key_handler(void);

#ifdef __cplusplus
}
#endif		/* __cplusplus */

#endif
